package query;

import index.HashIndex;
import global.Minibase;
import global.RID;
import global.SearchKey;
import heap.HeapFile;
import parser.AST_Insert;
import relop.Schema;
import relop.Tuple;

/**
 * Execution plan for inserting tuples.
 */
class Insert implements Plan {

	/**
	 * Optimizes the plan, given the parsed query.
	 * 
	 * @throws QueryException
	 *             if table doesn't exists or values are invalid
	 */
	// datamembers:
	protected String fileName;
	protected Schema s;
	protected IndexDesc[] idesc;
	int table_has_index;
	Object[] objs;

	public Insert(AST_Insert tree) throws QueryException {
		fileName = tree.getFileName();
		QueryCheck.tableExists(fileName);
		s = Minibase.SystemCatalog.getSchema(fileName);
		idesc = Minibase.SystemCatalog.getIndexes(fileName);
		table_has_index = idesc.length;

		/*
		 * For every new insert of tuple in a table, - insert that tuple in
		 * table - if index exists, then put the RID and searchkey in hashIndex
		 */

		objs = tree.getValues();

	} // public Insert(AST_Insert tree) throws QueryException

	/**
	 * Executes the plan and prints applicable output.
	 */
	public void execute() {
		
		//tuple => SEAARchkey => RID => put (searchkey , rid ) in hashindex but check before ...
		
		Tuple t = new Tuple (s, objs);
		RID rid = new HeapFile(fileName).insertRecord(t.getData()); // is this new OK ?
		Minibase.SystemCatalog.incrementTableCardinality(fileName, 1);

		/*
		 * RID insertRecord(byte[] record) Inserts a new record into the file
		 * and returns its RID.
		 */

		if (table_has_index != 0) {
			// insert in hashIndex
			for (IndexDesc id : idesc) {
				HashIndex hi = new HashIndex(id.indexName);
				String col_name = id.columnName;
				Object o = objs[s.fieldNumber(col_name)];
				SearchKey sk = new SearchKey (o);
				hi.insertEntry(sk, rid);
			} // for
		}

		// print the output message
		System.out.println("1 rows inserted. ");

		// TODO: increment count in sys catalog count

	} // public void execute()

} // class Insert implements Plan
